package com.dapeis.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.ag.core.exception.SysTipsException;
import com.ag.module.common.api.domain.NoticePush;
import com.ag.module.common.api.service.NoticePushService;
import com.ag.module.common.api.service.text.base.NoticeText;
import com.ag.utils.CollectionUtils;
import com.dapeis.im.tim.TIMUtil;
import com.google.gson.JsonArray;

/**
 * 极光推送
 * 
 * @author yuanyong
 *
 */

@Service
public class JPushService extends NoticePushService {

    @Resource
    CollocationService collocationService;

    /***
     * 推送
     * 
     * @param collocationId
     * @param nt
     * @return
     */
    public boolean pushMessage(Integer collocationId, NoticeText nt) {
	return addNoticePushToCollocation(collocationId, nt);
    }

    public boolean addNoticePushAndPushFromColloctaionIds(List<Integer> colloctaionIds,
	    NoticeText nt) {
	return addNoticePushAndPushWithCollocation(NoticePush.Flag.DeviceType.IDS, colloctaionIds, nt);
    }


    /**
     * 给单个用户推送通知
     * 
     * @param userId
     * @param thumbTitle
     * @param content
     * @param url
     * @return
     */
    public boolean addNoticePushToCollocation(Integer collocationId,
	    NoticeText nt) {
	List<Integer> collocationIds = new ArrayList<Integer>();
	collocationIds.add(collocationId);
	return addNoticePushAndPushFromIdsWithCollocation(collocationIds, nt);
    }

    public boolean addNoticePushAndPushFromIdsWithCollocation(
	    List<Integer> collocationIds, NoticeText nt) {
	return addNoticePushAndPushWithCollocation(
		NoticePush.Flag.DeviceType.IDS, collocationIds, nt);
    }

    public boolean addNoticePushAndPushWithCollocation(String deviceType,
	    List<Integer> collocationIds, NoticeText nt) {
	NoticePush noticePush = new NoticePush();
	noticePush.setContent(nt.content());
	noticePush.setTerminal(NoticePush.Flag.Terminal.PUSH_TERMINAL_APP_USER);
	noticePush.setThumbTitle(nt.title());
	noticePush.setUrl(nt.createUrl());
	noticePush.setTerminalIds(assembleTerminalIds(collocationIds));
	noticePush.setRecordCreateTime(System.currentTimeMillis() / 1000);
	noticePush.setDeviceType(deviceType);
	noticePush.setData(nt.setData());

	Map<String, List<String>> group = new HashMap<String, List<String>>();
	if (CollectionUtils.isEmpty(collocationIds)) {
	    if (NoticePush.Flag.DeviceType.ALL.equals(noticePush
		    .getDeviceType())) {// 全部设备，android、ios各推一次
		group.put(NoticePush.Flag.DeviceType.IOS, null);
		group.put(NoticePush.Flag.DeviceType.ANDROID, null);
	    } else {
		group.put(noticePush.getDeviceType(), null);
	    }

	} else {// 指定用户的ID推送，需要区分android还是ios的

	    List<Map<String, Object>> list = collocationService
		    .queryDeviceTypeForIds(collocationIds);
	    if (CollectionUtils.isEmpty(list)) {
		logger.error(
			"userService.queryUserListDeviceType return nil.userIds:{}",
			ToStringBuilder.reflectionToString(collocationIds));
		throw new SysTipsException("找不到推送目标的设备信息，请检查.");
	    }

	    for (Map<String, Object> m : list) {
		List<String> l = null;
		String deviceTypeDB = null;
		if (m.containsKey("deviceType")) {
		    deviceTypeDB = StringUtils.lowerCase(String.valueOf(m
			    .get("deviceType")));
		}

		String id = TIMUtil.DPS_USER
			.concat(String.valueOf(m.get("id")));
		// 后续有Android后需要添加Android的判断

		if (!(deviceTypeDB.equalsIgnoreCase("ipad") || deviceTypeDB
			.equalsIgnoreCase("iphone"))) {
		    logger.warn("该用户没有找到最近一次登陆的设备.{}, deviceTypeDB:", id,
			    deviceTypeDB);
		} else {
		    deviceTypeDB = NoticePush.Flag.DeviceType.IOS;
		}
		/*
		 * if (NoticePush.Flag.DeviceType.ANDROID
		 * .equalsIgnoreCase(deviceTypeDB) ||
		 * NoticePush.Flag.DeviceType.IOS
		 * .equalsIgnoreCase(deviceTypeDB)) {// 找不到最近一次登陆的设备 } else {
		 * logger.warn("该用户没有找到最近一次登陆的设备.{}, deviceTypeDB:", id,
		 * deviceTypeDB); }
		 */

		if (group.containsKey(deviceTypeDB)) {
		    l = group.get(deviceTypeDB);
		} else {
		    l = new ArrayList<String>();
		    group.put(deviceTypeDB, l);
		}

		l.add(String.valueOf(id));
	    }
	}

	JsonArray fetchDetails = fetch(group, nt);
	noticePush.setModifyTime(System.currentTimeMillis() / 1000);
	noticePush.setFetchDetail(fetchDetails.toString());

	boolean insert = insertSelective(noticePush) > 0;
	Assert.isTrue(insert);
	return insert;
    }

    @SuppressWarnings("rawtypes")
    private String assembleTerminalIds(Object o) {
	if (o == null) {
	    return null;
	}
	if (o instanceof List) {
	    List l = (List) o;
	    if (CollectionUtils.isEmpty(l))
		return null;
	    StringBuffer buffer = new StringBuffer(",");
	    for (Object object : l) {
		buffer.append(object).append(",");
	    }

	    return buffer.toString();
	} else {
	    return "," + o + ",";
	}
    }
}
